home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / devHBA.c.proto < prev    next >
Encoding:
Text File  |  1992-12-19  |  15.6 KB  |  481 lines

  1. /* 
  2.  * devHBA.c --
  3.  *
  4.  *    This is a prototype template descibing the Sprite interface to SCSI
  5.  *    (Small Computer System Interface) HBAs (Host Bus Adapters). This file
  6.  *    only descibes the interface from the machine independent part of the
  7.  *    device module to the HBA. This template assumes that the HBA is of
  8.  *    the sort that you send a command to the device and are interrupted
  9.  *    when the command completes.
  10.  *
  11.  * Copyright 1988 Regents of the University of California
  12.  * Permission to use, copy, modify, and distribute this
  13.  * software and its documentation for any purpose and without
  14.  * fee is hereby granted, provided that the above copyright
  15.  * notice appear in all copies.  The University of California
  16.  * makes no representations about the suitability of this
  17.  * software for any purpose.  It is provided "as is" without
  18.  * express or implied warranty.
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/devHBA.c.proto,v 9.0 89/09/12 14:58:20 douglis Stable $ SPRITE (Berkeley)";
  23. #endif not lint
  24.  
  25. #include "sprite.h"
  26. #include "scsi<HBATYPE>.h"
  27. #include "mach.h"
  28. #include "dev.h"
  29. #include "devInt.h"
  30. #include "scsiHBA.h"
  31. #include "scsiDevice.h"
  32. #include "sync.h"
  33. #include "stdlib.h"
  34.  
  35. /*
  36.  * Controller - The Data structure describing a <HBATYPE> controller. One
  37.  * of these structures exists for each active <HBATYPE> on the system. Each
  38.  * controller may have from zero to 56 (7 targets each with 8 logical units)
  39.  * devices attached to it. 
  40.  */
  41. typedef Controller struct Controller {
  42.     CtrlRegs *regsPtr;    /* Pointer to the registers of this controller. */
  43.     char    *name;    /* String for error message for this controller.  */
  44.     DevCtrlQueues devQueues;    /* Device queues for devices attached to this
  45.                  * controller.     */
  46.     Sync_Semaphore mutex; /* Lock protecting controller's data structures. */
  47.               /* Until disconnect/reconnect is added we can have
  48.                * only one current active device and scsi command.*/
  49.     Device     *devPtr;       /* Current active command. */
  50.     ScsiCmd   *scsiCmdPtr; /* Current active command. */
  51.     Device  *devicePtr[8][8]; /* Pointers to the device attached to the 
  52.                    * controller index by [targetID][LUN].
  53.                    * NIL if device not attached yet. Zero if
  54.                    * device conflicts with HBA address.  */
  55.  
  56. } Controller;
  57.  
  58. /*
  59.  * MAX_CTRLS -       Maximum number of <HBATYPE> controllers attached to the
  60.  *             system. We set this to the maximum number of VME slots
  61.  *             in any system currently available to us
  62.  */
  63. #define    MAX_CTRLS    16
  64. static Controller *Controllers[MAX_CTRLS];
  65.  
  66. /*
  67.  * Device - The data structure containing information about a device. One of
  68.  * these structure is kept for each attached device. Note that is structure
  69.  * is casted into a ScsiDevice and returned to higher level software.
  70.  * This implies that the ScsiDevice must be the first field in this
  71.  * structure.
  72.  */
  73.  
  74. typedef struct Device {
  75.     ScsiDevice handle;    /* Scsi Device handle. This is the only part
  76.              * of this structure visible to higher 
  77.              * level software. 
  78.              * MUST BE FIRST FIELD IN STRUCTURE. */
  79.     int    targetID;    /* SCSI Target ID of this device. Note that
  80.              * the LUN is store in the device handle. */
  81.     Controller *ctrlPtr;    /* Controller to which device is attached. */
  82.            /*
  83.             * The following part of this structure is 
  84.             * used to handle SCSI commands that return 
  85.             * CHECK status. To handle the REQUEST SENSE
  86.             * command we must: 1) Save the state of the current
  87.             * command into the "struct FrozenCommand". 2) Submit
  88.             * a request sense command formatted in SenseCmd
  89.             * to the device. */
  90.     struct FrozenCommand {               
  91.     ScsiCmd    *scsiCmdPtr;       /* The frozen command. */
  92.     unsigned char statusByte; /* It's SCSI status byte, Will always have
  93.                    * the check bit set.  */
  94.     int amountTransferred;    /* Number of bytes transferred by this 
  95.                    * command. */
  96.     } frozen;    
  97.     char senseBuffer[DEV_MAX_SENSE_BYTES]; /* Data buffer for request sense */
  98.     ScsiCmd        SenseCmd;         /* Request sense command buffer. */
  99. } Device;
  100.  
  101.  
  102. /*
  103.  *----------------------------------------------------------------------
  104.  *
  105.  * Dev<HBATYPE>Init --
  106.  *
  107.  *    This routine is called from the machine dependent part of the device
  108.  *    module at system boot time to probe for and initialize the HBA.
  109.  *
  110.  * Results:
  111.  *    TRUE if the HBA exists, FALSE otherwise.
  112.  *
  113.  * Side effects:
  114.  *    Memory may be allocated.
  115.  *
  116.  *----------------------------------------------------------------------
  117.  */
  118. Dev<HBATYPE>Init(ctrlLocPtr)
  119.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  120. {
  121.     int    ctrlNum;
  122.     Boolean    found;
  123.     Controller *ctrlPtr;
  124.     int    i,j;
  125.  
  126.     /*
  127.      * See if the controller is there. 
  128.      */
  129.     ctrlNum = ctrlLocPtr->controllerID;
  130.     found =  ProbeForHBA(ctrlLocPtr->address);
  131.     if (!found) {
  132.     return FALSE;
  133.     }
  134.     /*
  135.      * It's there. Allocate and fill in the Controller structure.
  136.      */
  137.     Controllers[ctrlNum] = ctrlPtr = (Controller *) malloc(sizeof(Controller));
  138.     bzero((char *) ctrlPtr, sizeof(Controller));
  139.     ctrlPtr->regsPtr = (CtrlRegs *) (ctrlLocPtr->address);
  140.     ctrlPtr->name = ctrlLocPtr->name;
  141.     Sync_SemInitDynamic(&(ctrlPtr->mutex),ctrlPtr->name);
  142.     /* 
  143.      * Initialized the name, device queue header, and the master lock.
  144.      * The controller comes up with no devices active and no devices
  145.      * attached.  Reserved the devices associated with the 
  146.      * targetID of the controller (7).
  147.      */
  148.     /*
  149.      * Allocate the device queue header for the devices attached to this
  150.      * HBA.  Note we share our MASTER_LOCK() with the DevQueue code to 
  151.      * much simply synronization. We are notified of incomming requests by
  152.      * the DevQueue module calls to entryAvailProc.
  153.      */
  154.     ctrlPtr->devQueues = Dev_CtrlQueuesCreate(&(ctrlPtr->mutex),entryAvailProc);
  155.     for (i = 0; i < 8; i++) {
  156.     for (j = 0; j < 8; j++) {
  157.         ctrlPtr->devicePtr[i][j] = (i == 7) ? (Device *) 0 : (Device *) NIL;
  158.     }
  159.     }
  160.     ctrlPtr->scsiCmdPtr = (ScsiCmd *) NIL;
  161.     Controllers[ctrlNum] = ctrlPtr;
  162.     Reset(ctrlPtr);
  163.     return TRUE;
  164. }
  165.  
  166.  
  167. /*
  168.  *----------------------------------------------------------------------
  169.  *
  170.  * Dev<HBATYPE>AttachDevice --
  171.  *
  172.  *    Attach a SCSI device using the Sun SCSI3 HBA. 
  173.  *
  174.  * Results:
  175.  *    None.
  176.  *
  177.  * Side effects:
  178.  *    None.
  179.  *
  180.  *----------------------------------------------------------------------
  181.  */
  182.  
  183. ScsiDevice   *
  184. Dev<HBATYPE>AttachDevice(devicePtr, insertProc)
  185.     Fs_Device    *devicePtr;     /* Device to attach. */
  186.     void    (*insertProc)(); /* Queue insert procedure. */
  187. {
  188.     Device *devPtr;
  189.     Controller    *ctrlPtr;
  190.     char   tmpBuffer[512];
  191.     int       length;
  192.     int       ctrlNum;
  193.     int       targetID, lun;
  194.  
  195.     /*
  196.      * The Fs_Device structure tells the attach procedure the HBA controller
  197.      * number (only useful on machine that can have more than on controller
  198.      * of a certain type) and the SCSI TargetID and LUN of the device.
  199.      * This code here assumes that the machine depended part of the device
  200.      * module has probed for and filled in the Controllers array.
  201.      */
  202.     ctrlNum = SCSI_HBA_NUMBER(devicePtr);
  203.     if ((ctrlNum > MAX_CTRLS) ||
  204.     (Controllers[ctrlNum] == (Controller *) 0)) { 
  205.     return (ScsiDevice  *) NIL;
  206.     } 
  207.     ctrlPtr = Controllers[ctrlNum];
  208.     targetID = SCSI_TARGET_ID(devicePtr);
  209.     lun = SCSI_LUN(devicePtr);
  210.     MASTER_LOCK(&(ctrlPtr->mutex));
  211.     /*
  212.      * A device pointer of zero means that targetID/LUN 
  213.      * conflicts with that of the HBA. A NIL means the
  214.      * device hasn't been attached yet.
  215.      */
  216.     if (ctrlPtr->devicePtr[targetID][lun] == (Device *) 0) {
  217.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  218.     return (ScsiDevice *) NIL;
  219.     }
  220.     if (ctrlPtr->devicePtr[targetID][lun] != (Device *) NIL) {
  221.     /*
  222.      * Already attached once before. Use the cached value.
  223.      */
  224.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  225.     return (ScsiDevice *) (ctrlPtr->devicePtr[targetID][lun]);
  226.     }
  227.     /*
  228.      * Allocate and fill in a ScsiDevice structure for the new device.
  229.      */
  230.     ctrlPtr->devicePtr[targetID][lun] = devPtr =
  231.                     (Device *) malloc(sizeof(Device));
  232.     bzero((char *) devPtr, sizeof(Device));
  233.     /*
  234.      * Fill in the ScsiDevice structure that is returned to the caller.
  235.      * It starts with a device queue for the device.
  236.      */
  237.     devPtr->handle.devQueue = Dev_QueueCreate(ctrlPtr->devQueues, 0,
  238.                 insertProc, (ClientData) devPtr);
  239.     /*
  240.      * Followed by a printable string sepcifying the devices location.
  241.      */
  242.     (void) sprintf(tmpBuffer, "%s#%d Target %d LUN %d", ctrlPtr->name, ctrlNum,
  243.             devPtr->targetID, devPtr->handle.LUN);
  244.     length = strlen(tmpBuffer);
  245.     devPtr->handle.locationName = (char *) strcpy(malloc(length+1),tmpBuffer);
  246.     /*
  247.      * And the logical unit number. This is need because the LUN is formatted
  248.      * into scsi control blocks by the higher level software.
  249.      */
  250.     devPtr->handle.LUN = lun;
  251.     /*
  252.      * The procedure of ours to call when releasing the device.
  253.      */
  254.     devPtr->handle.releaseProc = ReleaseProc;
  255.     /*
  256.      * The last part of the handle we need to fill in is the maximum size
  257.      * transfer this HBA can support.
  258.      */
  259.     devPtr->handle.maxTransferSize = MAX_DMA_SIZE;
  260.  
  261.     devPtr->targetID = targetID;
  262.     devPtr->ctrlPtr = ctrlPtr;
  263.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  264.     return (ScsiDevice *) devPtr;
  265. }
  266.  
  267.  
  268. /*
  269.  *----------------------------------------------------------------------
  270.  *
  271.  * Dev<HBATYPE>Intr --
  272.  *
  273.  * Handle a SCSI command finished interrupt for the <HBATYPE> controller.
  274.  *
  275.  * Side effects:
  276.  *    Usually a process is notified that an I/O has completed.
  277.  *
  278.  *----------------------------------------------------------------------
  279.  */
  280. Dev<HBATYPE>Intr(ctrlPtr)
  281.     Controller *ctrlPtr;    /* Controller interrupt was from. */
  282. {
  283.     register CtrlRegs *regsPtr;
  284.     Device    *devPtr;
  285.     unsigned char statusByte;
  286.     List_Links    *newRequestPtr;
  287.     ClientData    clientData;
  288.  
  289.     /*
  290.      * Need to determine the device, request, statusByte and residual from
  291.      * the command.
  292.      */
  293.     MASTER_LOCK(&(ctrlPtr->mutex));
  294.     devPtr = ctrlPtr->scsiCmdPtr;
  295.     scsiCmdPtr = ctrlPtr->scsiCmdPtr;
  296.     residual = ctrlPtr->regs->residual;
  297.     statusByte = ctrlPtr->regs->statusByte;
  298.     /*
  299.      * Use the request done procedure to notify the requestor.
  300.      */
  301.     RequestDone(devPtr, scsiCmdPtr, SUCCESS, statusByte,
  302.             scsiCmdPtr->bufferLen - residual);
  303.  
  304.     /*
  305.      * If the controller is not busy get another request from the queue and
  306.      * start it.
  307.      */
  308.     if (!IS_CTRL_BUSY(ctrlPtr)) {
  309.        newRequestPtr = Dev_QueueGetNextFromSet(ctrlPtr->devQueues,
  310.                 DEV_QUEUE_ANY_QUEUE_MASK,&clientData);
  311.        if (newRequestPtr != (List_Links *) NIL) { 
  312.         entryAvailProc(clientData,newRequestPtr);
  313.        }
  314.     }
  315.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  316.     return ;
  317.  
  318. }
  319.  
  320.  
  321. /*
  322.  *----------------------------------------------------------------------
  323.  *
  324.  * entryAvailProc --
  325.  *
  326.  *    Act upon an entry becomming available in the queue for this
  327.  *    controller. This routine is the Dev_Queue callback function that
  328.  *    is called whenever work becomes available for this controller. 
  329.  *    If the controller is not already busy we start the
  330.  *    request.
  331.  *    NOTE: This routine is also called from DevSCSI3Intr to start the
  332.  *    next request after the previously one finishes.
  333.  *
  334.  * Results:
  335.  *    TRUE if we were able to process the requests. FALSE if the device 
  336.  *    module should re-enqueue the request.
  337.  *
  338.  * Side effects:
  339.  *    Request may submitted to the device. Request callback
  340.  *    function may be called.
  341.  *
  342.  *----------------------------------------------------------------------
  343.  */
  344.  
  345. static Boolean
  346. entryAvailProc(clientData, newRequestPtr) 
  347.    ClientData    clientData;    /* Really the Device this request ready. */
  348.    List_Links *newRequestPtr;    /* The new SCSI request. */
  349. {
  350.     register Device *devPtr = (Device *) clientData;
  351.     register Controller *ctrlPtr = devPtr->ctrlPtr;
  352.     register ScsiCmd    *scsiCmdPtr = (ScsiCmd *) newRequestPtr;
  353.     ReturnStatus    status;
  354.  
  355.     /*
  356.      * If we are busy (have an active request) just return. Otherwise 
  357.      * start the request.
  358.      */
  359.  
  360.     if (IS_CTRL_BUSY(ctrlPtr)) { 
  361.     return FALSE;
  362.     }
  363.     /*
  364.      * Call the function to send the SCSI command to the device. 
  365.      */
  366.     status = StartCommand(devPtr, scsiCmdPtr);
  367.     /*    
  368.      * If the command couldn't be started do the callback function.
  369.      */
  370.     if (status != SUCCESS) {
  371.      RequestDone(devPtr,scsiCmdPtr,status,0,0);
  372.     }
  373.     return TRUE;
  374.  
  375. }   
  376.  
  377.  
  378. /*
  379.  *----------------------------------------------------------------------
  380.  *
  381.  * RequestDone --
  382.  *
  383.  *    Process a request that has finished. Unless a SCSI check condition
  384.  *    bit is present in the status returned, the request call back
  385.  *    function is called.  If check condition is set we fire off a
  386.  *    SCSI REQUEST SENSE to get the error sense bytes from the device.
  387.  *
  388.  * Results:
  389.  *    None.
  390.  *
  391.  * Side effects:
  392.  *    The call back function may be called.
  393.  *
  394.  *----------------------------------------------------------------------
  395.  */
  396.  
  397. void
  398. RequestDone(devPtr,scsiCmdPtr,status,scsiStatusByte,amountTransferred)
  399.     Device    *devPtr;    /* Device for request. */
  400.     ScsiCmd    *scsiCmdPtr;    /* Request that finished. */
  401.     ReturnStatus status;    /* Status returned. */
  402.     unsigned char scsiStatusByte;    /* SCSI Status Byte. */
  403.     int        amountTransferred; /* Amount transferred by command. */
  404. {
  405.     ReturnStatus    senseStatus;
  406.     Controller            *ctrlPtr = devPtr->ctrlPtr;
  407.  
  408.  
  409.     if (debug > 3) {
  410.     printf("RequestDone for %s status 0x%x scsistatus 0x%x count %d\n",
  411.         devPtr->handle.locationName, status,scsiStatusByte,
  412.         amountTransferred);
  413.     }
  414.     /*
  415.      * First check to see if this is the reponse of a HBA generated 
  416.      * REQUEST SENSE command.  If this is the case, we can process
  417.      * the callback of the frozen command for this device and
  418.      * allow the flow of command to the device to be resummed.
  419.      */
  420.     if (scsiCmdPtr->doneProc == SpecialSenseProc) {
  421.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  422.     (devPtr->frozen.scsiCmdPtr->doneProc)(devPtr->frozen.scsiCmdPtr, 
  423.             SUCCESS,
  424.             devPtr->frozen.statusByte, 
  425.             devPtr->frozen.amountTransferred,
  426.             amountTransferred,
  427.             devPtr->senseBuffer);
  428.      MASTER_LOCK(&(ctrlPtr->mutex));
  429.      SET_CTRL_FREE(ctrlPtr);
  430.      return;
  431.     }
  432.     /*
  433.      * This must be a outside request finishing. If the request 
  434.      * suffered an error or the HBA or the scsi status byte
  435.      * says there is no error sense present, we can do the
  436.      * callback and free the controller.
  437.      */
  438.     if ((status != SUCCESS) || !SCSI_CHECK_STATUS(scsiStatusByte)) {
  439.      MASTER_UNLOCK(&(ctrlPtr->mutex));
  440.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  441.                    amountTransferred, 0, (char *) 0);
  442.      MASTER_LOCK(&(ctrlPtr->mutex));
  443.      SET_CTRL_FREE(ctrlPtr);
  444.      return;
  445.    } 
  446.    /*
  447.     * If we got here than the SCSI command came back from the device
  448.     * with the CHECK bit set in the status byte.
  449.     * Need to perform a REQUEST SENSE. Move the current request 
  450.     * into the frozen state and issue a REQUEST SENSE. 
  451.     */
  452.    devPtr->frozen.scsiCmdPtr = scsiCmdPtr;
  453.    devPtr->frozen.statusByte = scsiStatusByte;
  454.    devPtr->frozen.amountTransferred = amountTransferred;
  455.    /*
  456.     * Use the routine DevScsiSenseCmd to quick format a REQUEST_SENSE
  457.     * command for the device.
  458.     */
  459.    DevScsiSenseCmd((ScsiDevice *)devPtr, DEV_MAX_SENSE_BYTES, 
  460.            devPtr->senseBuffer, &(devPtr->SenseCmd));
  461.    /*
  462.     * Use a special procedure so we can tell we one of our REQUEST_SENSE
  463.     * finishes.
  464.     */
  465.    devPtr->SenseCmd.doneProc = SpecialSenseProc,
  466.    senseStatus = StartCommand(devPtr, &(devPtr->SenseCmd));
  467.    /*
  468.     * If we got an HBA error on the REQUEST SENSE we end the outside 
  469.     * command with the SUCCESS status but zero sense bytes returned.
  470.     */
  471.    if (senseStatus != SUCCESS) {
  472.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  473.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  474.                    amountTransferred, 0, (char *) 0);
  475.         MASTER_LOCK(&(ctrlPtr->mutex));
  476.     SET_CTRL_FREE(ctrlPtr);
  477.    }
  478.  
  479. }
  480.  
  481.